AWS CloudShellからAmazon EFSをマウントしてみた

AWS CloudShellからAmazon EFSをマウントしてみた

Clock Icon2024.07.29

弊社の下記ブログで紹介されているようにCloudShellがVPCに接続できるようになりました。
CloudShellからEFSもマウントできるのか気になったので試してみました。

構成

簡単になりますが、今回作成する構成は以下になります。
efs

サブネットを1つ作成してその中にEFSのマウントターゲットとCloudShellのENIを作成してマウントを行います。

設定

AWSリソースの作成は以下のCloudFormationテンプレートで作成を行いました。

AWSTemplateFormatVersion: "2010-09-09"

Description: Network Stack

Metadata:
# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------# 
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label: 
          default: Parameters for System Name Prefix
        Parameters:
          - SystemPrefix
          - Environment
      - Label: 
          default: Parameters for VPC
        Parameters:
          - VPCCIDR
      - Label: 
          default: Parameters for Subnet
        Parameters:
          - PublicSubnet01CIDR

Parameters:
# ------------------------------------------------------------#
# Parameters
# ------------------------------------------------------------# 
  SystemPrefix:
    Default: test
    Type: String

  Environment:
    AllowedValues:
      - dev
      - prod
      - stg
    Default: dev
    Type: String

  VPCCIDR:
    Default: 10.0.0.0/16
    Type: String

  PublicSubnet01CIDR:
    Default: 10.0.0.0/24
    Type: String

Resources:
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------# 
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VPCCIDR
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags: 
        - Key: Name
          Value: !Sub ${SystemPrefix}-${Environment}-vpc

# ------------------------------------------------------------#
# InternetGateway
# ------------------------------------------------------------# 
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags: 
        - Key: Name
          Value: !Sub ${SystemPrefix}-${Environment}-igw

  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC

# ------------------------------------------------------------#
# Subnet
# ------------------------------------------------------------# 
  PublicSubnet01:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: ap-northeast-1a
      CidrBlock: !Ref PublicSubnet01CIDR
      MapPublicIpOnLaunch: true
      Tags: 
        - Key: Name
          Value: !Sub ${SystemPrefix}-${Environment}-pub-01
      VpcId: !Ref VPC

# ------------------------------------------------------------#
# RouteTable
# ------------------------------------------------------------# 
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${SystemPrefix}-${Environment}-public-rtb

  PublicRouteTableRoute:
    Type: AWS::EC2::Route
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
      RouteTableId: !Ref PublicRouteTable

  PublicRtAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet01

# ------------------------------------------------------------#
# Security Group
# ------------------------------------------------------------# 
  EFSSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: for EFS
      GroupName: !Sub ${SystemPrefix}-${Environment}-efs-sg
      SecurityGroupEgress: 
        - CidrIp: 0.0.0.0/0
          FromPort: -1
          IpProtocol: -1
          ToPort: -1
      SecurityGroupIngress: 
        - SourceSecurityGroupId: !Ref CloudShellSG
          FromPort: 2049
          IpProtocol: tcp
          ToPort: 2049
      Tags: 
        - Key: Name
          Value: !Sub ${SystemPrefix}-${Environment}-efs-sg
      VpcId: !Ref VPC

  CloudShellSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: for CloudShell
      GroupName: !Sub ${SystemPrefix}-${Environment}-cloudshell-ingress-sg
      SecurityGroupEgress: 
        - CidrIp: 0.0.0.0/0
          FromPort: -1
          IpProtocol: -1
          ToPort: -1
      Tags: 
        - Key: Name
          Value: !Sub ${SystemPrefix}-${Environment}-cloudshell-sg
      VpcId: !Ref VPC

# ------------------------------------------------------------#
# EFS
# ------------------------------------------------------------# 
  EFS:
    Type: AWS::EFS::FileSystem
    Properties:
      Encrypted: true
      FileSystemTags: 
      - Key: Name
        Value: !Sub ${SystemPrefix}-${Environment}-efs

  MountTarget1:
    Type: AWS::EFS::MountTarget
    Properties:
      FileSystemId: !Ref EFS
      SecurityGroups: 
        - !Ref EFSSG
      SubnetId: !Ref PublicSubnet01

# ------------------------------------------------------------#
# ElasticIP
# ------------------------------------------------------------# 
  EIP:
    Type: AWS::EC2::EIP
    Properties: 
      Domain: vpc
      Tags:
        - Key: Name
          Value: !Sub ${SystemPrefix}-${Environment}-eip

上記のCloudFormationテンプレートでは構成図で紹介したリソースとElasticIP (177~183行目) を作成しています。
このElasticIPはCloudShellのENIにアタッチしてパブリックネットワークへアクセスできるようにします。

CloudFormationのデプロイは以下のコマンドを実行します。

aws cloudformation create-stack --stack-name CloudFormationスタック名 --template-body file://CloudFormationテンプレートファイル名

デプロイが完了したらCloudShellをVPCに接続します。
VPCへの接続は以下のブログで紹介されている手順で行います。
セキュリティグループは「test-dev-cloudshell-sg」を選択してください。
https://dev.classmethod.jp/articles/cloudshell-vpc-environment/#%25E3%2582%2584%25E3%2581%25A3%25E3%2581%25A6%25E3%2581%25BF%25E3%2581%259F

接続ができたら以下のURLからENIのコンソールを開いてCloudShellのENIを選択してください。
https://ap-northeast-1.console.aws.amazon.com/ec2/home?region=ap-northeast-1#NIC:v=3;$case=tags:false\,client:false;$regex=tags:false\,client:false

CloudShellのENIは説明に「Elastic network interface managed by AWS CloudShell service.」と記載されています。
CloudShellのENIを選択したら「ネットワークインターフェイス ID」をメモしておいてください。(ElasticIPをアタッチするときに使用します)
スクリーンショット 2024-07-29 232222
「ネットワークインターフェイス ID」をメモしたら以下のURLからElasticIPのコンソールを開いてください。
ttps://ap-northeast-1.console.aws.amazon.com/ec2/home?region=ap-northeast-1#Addresses:

開いたらElasticIPを選択してアクションから「Elastic IP アドレスの関連付け」をクリックしてください。
スクリーンショット 2024-07-29 232801
クリックしたらリソースタイプで「ネットワークインターフェース」を選択してネットワークインターフェイスで先ほどメモした「ネットワークインターフェイス ID」を入力してください。
入力を行ったら画面下の「関連付ける」をクリックしてください。
スクリーンショット 2024-07-29 233053
ここまで作業が完了したらCloudShellに戻って以下のコマンドを実行してレスポンスにElasticIPが出力されることを確認してください。

curl -4 ifconfig.io

ElasticIPが確認できたら以下のコマンドでCloudShellにnfs-utilsをインストールします。

sudo dnf install nfs-utils -y

マウント

上記の手順でマウントするための下準備ができたので実際にマウントしてみます。

以下のURLからEFSコンソールを開き作成したファイルシステムのIDをメモします。(今回のCloudFormationで作成している場合はtest-dev-efsという名前で作成されています)
https://ap-northeast-1.console.aws.amazon.com/efs/home?region=ap-northeast-1#/file-systems

スクリーンショット 2024-07-29 233913
メモしたらCloudShellで以下のコマンドを実行してマウントを行います。
コマンドの「ファイルシステムID」は先ほどメモしたものに置き換えてください。
マウントを行う際にルートユーザーでマウントされるのでchownコマンドでcloudshell-userユーザーにディレクトリの所有者を変更しています。

mkdir efs
sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport ファイルシステムID.efs.ap-northeast-1.amazonaws.com:/ efs
sudo chown -R cloudshell-user:cloudshell-user efs

mountコマンドを実行すると末尾にマウントしたファイルシステムが確認できます。
無事CloudShellからEFSがマウントできました。

mount
...
...
ファイルシステムID.efs.ap-northeast-1.amazonaws.com:/ on /home/cloudshell-user/efs type nfs4 (rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.0.87,local_lock=none,addr=10.0.0.61)

さいごに

CloudShellがVPCに接続できるようになったことで検証の行いやすさが格段に上がったと思います。
VPC上のリソースの接続確認であれば基本的にCloudShellがあれば問題無いように思いました。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.